package container

import (
	"n-server/config"
	"n-server/internal/handler"
	"n-server/internal/repository"
	"n-server/internal/router"
	"n-server/internal/service"
	"n-server/pkg/cache"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
	"gorm.io/gorm"
)

// Container 使用 wire 风格的依赖注入容器
type Container struct {
	config *config.Config

	// 所有依赖都通过接口定义
	UserRepository repository.UserRepository
	UserService    service.UserService
	UserHandler    handler.UserHandler
	HealthHandler  handler.HealthHandler
}

// Init 初始化创建 wire 风格的容器
func Init(c *config.Config, db *gorm.DB, rdb *redis.Client, cache cache.Cache) *Container {
	// 按照依赖关系顺序初始化
	userRepository := provideUserRepository(db)
	userService := provideUserService(userRepository, rdb, cache)
	userHandler := provideUserHandler(userService)
	healthHandler := provideHealthHandler()

	return &Container{
		config: c,
		UserRepository: userRepository,
		UserService:   userService,
		UserHandler:   userHandler,
		HealthHandler: healthHandler,
	}
}

// SetupRouter 创建路由实例
func (c *Container) SetupRouter() *gin.Engine {
	return router.Setup(
		&c.UserHandler,
		&c.HealthHandler,
	)
}

// 提供者函数（类似 wire 的 provide 函数）
func provideUserRepository(db *gorm.DB) repository.UserRepository {
	return repository.NewUserRepository(db)
}
func provideUserService(userRepository repository.UserRepository, redis *redis.Client, cache cache.Cache) service.UserService {
	return service.NewUserService(userRepository, redis, cache)
}

func provideUserHandler(userService service.UserService) handler.UserHandler {
	return *handler.NewUserHandler(userService)
}

func provideHealthHandler() handler.HealthHandler {
	return *handler.NewHealthHandler()
}